﻿<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title></title>
	<link href="js-console.css" rel="stylesheet" />
	<!-- 3. Write a function that makes a deep copy of an object
		* The function should work for both primitive and reference types -->
	<style>
		strong, em {
			text-decoration: underline;
		}
		em{
			padding-left: 20px;
		}
	</style>
</head>
<body>
	<div id="js-console"></div>
	<script src="js-console.js"></script>
	<script>
		// Helper functions
		function isPrimitive(src) {
			return !(typeof src === typeof new Object());
		}

		function generateNewObject(obj) {
			var res;

			if (obj instanceof Array) {
				res = new Array();
			}
			else if (obj instanceof Date) {
				res = new Date(obj.valueOf());
			}
			else if (obj instanceof String) {
				res = new String(obj.valueOf());
			}
			else if (obj instanceof Boolean) {
				res = new Boolean(obj.valueOf());
			}
			else if (obj instanceof Number) {
				res = new Number(obj.valueOf());
			}
			else if (obj === null) {
				res = null;
			}
			else if (obj === undefined) {
				res = undefined;
			}
			else {
				res = new Object();
			}

			return res;
		}

		// The main function
		function deepCopy(src) {
			var res;

			if (isPrimitive(src)) {
				res = src;
			}
			else {
				res = generateNewObject(src);
				for (var i in src) {
					res[i] = deepCopy(src[i]);
				}
			}

			return res;
		}

		// Prints Object properties
		function printObject(obj) {
			for (var i in obj) {
				jsConsole.write("<em>" + i + "</em>: ");

				var value = "";

				if (obj[i] === null) {
					value = "--null--";
				}
				else if (obj[i] === undefined) {
					value = "--undefined--";
				}
				else {
					value = obj[i];
				}

				jsConsole.writeLine(value);
			}
		}

		//----------------------------------
		// Test Deep Copy
		//----------------------------------
		var src = {};
		src.arr = new Array("123", new Number(2), false);
		src.num = 1;
		src.date = new Date(2013, 1, 1);
		src.num = new Number(2);
		src.str = new String("str obj");
		src.boo = new Boolean(true);
		src.ud = undefined;
		src.nu = null;

		// Do the magic
		var des = deepCopy(src);

		jsConsole.writeLine("<strong>Source Object</strong>");
		printObject(src);
		jsConsole.writeLine("<strong>Destination Object</strong>");
		printObject(des);

		// Change source object
		src.arr[0] = 777;
		src.num = 999;
		src.date = new Date();
		src.str = "new string";
		src.boo = false;

		jsConsole.writeLine("------------------------------------------------");
		jsConsole.writeLine("-- Source object changed ");
		jsConsole.writeLine("------------------------------------------------");
		jsConsole.writeLine("<strong>Source Object</strong>");
		printObject(src);
		jsConsole.writeLine("<strong>Destination Object</strong>");
		printObject(des);
	</script>
	
</body>
</html>
